package com.tp2.bo.impl;

import com.tp2.bo.Oferta;
import com.tp2.dominio.Descuento;
import com.tp2.dominio.MedioDePago;
import com.tp2.dominio.Producto;
import com.tp2.dominio.TarjetaDescuento;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class OfertaProducto extends Oferta {

    private Map<Producto, Double> productosAdheridos;
    private List<Producto> productosExcluidos;
    
    public OfertaProducto() {
    	super();
        productosAdheridos = new LinkedHashMap<Producto, Double>();
        productosExcluidos = new ArrayList<Producto>();
        this.setPrioridad(1);
    }

    @Override
    public List<Descuento> aplicar(List<Producto> productos, MedioDePago medioDePagoCompra, TarjetaDescuento tarjetaDescuento) {
    	

    	List<Descuento> descuentosAplicados = new ArrayList<Descuento>();
    	List<Descuento> descuentosEncontrados = new ArrayList<Descuento>();
    	
        int prodcutosEncontradosEnLista = 0;
        boolean huboCambios = true;

        while (huboCambios && getProductosAdheridos().size()>0 ) {
        	int productosEncontrados = 0;
        	descuentosEncontrados.clear();
            
        	for (Map.Entry<Producto, Double> productoAdherido : getProductosAdheridos().entrySet()) {

                huboCambios = false;
                
                for (Producto producto : productos) {
                    //seteo con P (Provisorio) a los productos que van aplicando a la oferta.
                    if (producto.getAplicoDescuento().isEmpty() && productoAdherido.getKey().equals(producto)
                            && !esExcluido(producto) && esMedioDePagoValido(medioDePagoCompra) 
                            && esTarjetaDeDescuentoValida(tarjetaDescuento)) {
                    	
                        producto.setAplicoDescuento("P");
                        huboCambios = true;
                        productosEncontrados++;
                        prodcutosEncontradosEnLista++;
                        if (productoAdherido.getValue() != 0 ) {
                            Double descuento = ((producto.getPrecio()) * (productoAdherido.getValue())) / 100;
                            descuentosEncontrados.add(new Descuento(getDescripcion(), descuento));
                            producto.setPrecioConDescuento(producto.getPrecio() - descuento);
                        }
                        
                        if (productosEncontrados == getProductosAdheridos().size()){
                                        	 	descuentosAplicados.addAll(descuentosEncontrados);
                        }
                        
                        break;
                    }
                }
                if (!huboCambios) {
                    break;
                }
            }
        }

        int cantidadDePromocionesEncontradas = prodcutosEncontradosEnLista / getProductosAdheridos().size();
        int cantidadDeMarcadosSinPromocion = prodcutosEncontradosEnLista % getProductosAdheridos().size();

        //Marco definitivamente a los que si aplicaron a la promocion
        for (int i = 0; i < cantidadDePromocionesEncontradas; i++) {
            //seteo con D (Definitivo) a los productos que aplicaron para la oferta.
            int cantidad = getProductosAdheridos().size();

            for (Producto producto : productos) {
                if (producto.getAplicoDescuento().equals("P")) {
                    producto.setAplicoDescuento("D");
                    cantidad--;
                }
                if (cantidad == 0) {
                    break;
                }
            }
        }

        //Desmarco a los que no aplicaron a la promocion
        for (int i = 0; i < cantidadDeMarcadosSinPromocion; i++) {
            //seteo con vacio a los productos que no pudieron aplicar en la oferta.
            for (Producto producto : productos) {
                if (producto.getAplicoDescuento().equals("P")) {
                    producto.setAplicoDescuento("");
                    producto.setPrecioConDescuento(producto.getPrecio());
                }
            }
        }

        return descuentosAplicados;
    }
    
    public Map<Producto, Double> getProductosAdheridos() {
        return productosAdheridos;
    }

    public void setProductosAdheridos(Map<Producto, Double> productosAdheridos) {
        this.productosAdheridos = productosAdheridos;
    }

    public List<Producto> getProductosExcluidos() {
        return productosExcluidos;
    }

    public void setProductosExcluidos(List<Producto> productosExcluidos) {
        this.productosExcluidos = productosExcluidos;
    }

    public boolean esExcluido(Producto producto) {

        if (getProductosExcluidos().size() > 0) {
            for (Producto productoExcluido : getProductosExcluidos()) {
                if (producto.equals(productoExcluido)) {
                    return true;
                }
            }
        }
        return false;
    }

    public String getDescripcion(){
    	
    	if (descripcion == null){
        
    		return "Descuento por Cantidad";
    	}
    	
    	return descripcion;
    		
    }


}
